//
//  CuttingPhotos.cpp
//  BayMaxPuzzle
//
//  Created by Jacky on 15/3/28.
//
//

#include "CuttingPhotos.h"
#include "Global.h"

CuttingPhotos::CuttingPhotos():
_rows(3),
_columns(3),
_isTouching(false),
_isEnabled(true)
{
    
}

CuttingPhotos::~CuttingPhotos()
{
    this->removeAllChildren();
}

CuttingPhotos* CuttingPhotos::create(std::string photo,unsigned int rows,unsigned int columns)
{
    CuttingPhotos *cp=new CuttingPhotos();
    
    if (cp && cp->initWithPhoto(photo,rows,columns)) {
        cp->autorelease();
        return cp;
    }
    
    CC_SAFE_DELETE(cp);
    
    return nullptr;
}

bool CuttingPhotos::initWithPhoto(std::string photo,unsigned int rows,unsigned int columns)
{
    bool result;//初始化是否成功
    
    if (Layer::init()) {
        
        ignoreAnchorPointForPosition(false);
        _rows=rows;
        _columns=columns;
        
        
        if (initSlice(photo)) {
            
            initTouchEventlistener();
            
//            do{
                restart();
//            }while(checkIsWin());
            
            result=true;
        }else{
            result=false;
        }
        
    }else{
        result =false;
    }
    
    return result;
    
}

bool CuttingPhotos::initSlice(std::string photo)
{
    Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(photo);
    
    if (texture==nullptr) {
        return false;
    }
    
    //初始化存储行列的列表
    for (int x=0; x<_rows; ++x) {
        std::vector<Sprite*> row;
        for (int y=0; y<_columns; ++y) {
            row.push_back(nullptr);
        }
        
        _slices.push_back(row);
    }
    
    //计算图片每列的宽度
    auto size=texture->getContentSize();
    _sliceWidth=size.width/_columns;
    _sliceHeight=size.height/_rows;
    
    this->setContentSize(size);//设置Layer大小
    
    //最后一块
    auto endSlice=Sprite::createWithTexture(texture,Rect(_sliceWidth*(_columns-1),_sliceHeight*(_rows-1),_sliceWidth,_sliceHeight));
    endSlice->setTag(_columns*_rows-1);
    endSlice->setAnchorPoint(Vec2(0,0));
    endSlice->setPosition((_columns-1)*_sliceWidth,0);
    endSlice->setOpacity(120);//降低透明度
    this->addChild(endSlice);
    
    _slices[_rows-1][_columns-1]=nullptr;//设为空，表示这格可以移入
    
    
    //创建切片
    for (int x=0; x<_rows; ++x) {
        for (int y=0; y<_columns; ++y) {
            
            if (x==_rows-1 && y==_columns-1) {
                //最后一块不需要
                break;
            }
            
            Sprite* slice=Sprite::createWithTexture(texture,Rect(_sliceWidth*y,_sliceHeight*x,_sliceWidth,_sliceHeight));
            slice->setTag(y+_rows*x);
            slice->setAnchorPoint(Vec2(0,0));
            slice->setPosition(y*_sliceWidth,size.height-(x+1)*_sliceHeight);
            this->addChild(slice);
            
            _slices[x][y]=slice;
        }
    }
    
    return true;
}

void CuttingPhotos::initTouchEventlistener()
{
    auto listener = EventListenerTouchOneByOne::create();
    
    listener->onTouchBegan = [=](Touch *touch,Event *event){
        
        Point locationInNode = this->convertToNodeSpace(touch->getLocation());
        Size s = this->getContentSize();
        Rect rect = Rect(0, 0, s.width, s.height);
        
        if (rect.containsPoint(locationInNode) && !_isTouching && _isEnabled)
        {
            return true;
        }else{
            return false;
        }
    };
    
    listener->onTouchEnded=[=](Touch *touch,Event *event){
        Point locationInNode = this->convertToNodeSpace(touch->getLocation());
        
        int row=_rows-static_cast<int>(floor(locationInNode.y/this->_sliceHeight))-1;
        int col=static_cast<int>(floor(locationInNode.x/this->_sliceWidth));
        
        this->move(row, col);
    };
    
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}



void CuttingPhotos::move(int row,int col)
{
    auto slice=_slices[row][col];
    
    if (slice==nullptr) {
        return;
    }
    
    //查找周围是否有空白的区域
    bool isFind=false;
    Point targetPos;
    if (row<_rows-1 && _slices[row+1][col]==nullptr) {//down
        targetPos.x = row+1;
        targetPos.y = col;
        isFind=true;
    }else if (row>0 && _slices[row-1][col]==nullptr) {//up
        targetPos.x = row-1;
        targetPos.y = col;
        isFind=true;
    }else if (col>0 && _slices[row][col-1]==nullptr) {//left
        targetPos.x = row;
        targetPos.y = col-1;
        isFind=true;
    }else if (col<_columns-1 && _slices[row][col+1]==nullptr) {//right
        targetPos.x = row;
        targetPos.y = col+1;
        isFind=true;
    }
    
    if (isFind==false) {
        return;
    }
    
    auto callfunc1 = CallFunc::create([=](){
        _isTouching = true;
    });
    auto moveto = MoveTo::create(0.2, Vec2(targetPos.y*_sliceWidth,_sliceHeight*_rows-(targetPos.x+1)*_sliceHeight));
    auto callfunc2 = CallFunc::create([=](){
        _isTouching = false;
        if(this->checkIsWin()){
            EventCustom event("game_win");
            _eventDispatcher->dispatchEvent(&event);
        }
    });
    AUDIOENGINE_PLAY_MOVE_FX;
    slice->runAction(Sequence::create(callfunc1, moveto, callfunc2, nullptr));
    _slices[targetPos.x][targetPos.y]=slice;
    _slices[row][col]=nullptr;
}

void CuttingPhotos::restart()
{
    //取出所有切片
    cocos2d::Vector<Sprite*> list;
    
    for (int x=0; x<_rows; ++x) {
        for (int y=0; y<_columns; ++y) {
            auto slice= _slices[x][y];
            if (slice!=nullptr) {
                list.pushBack(slice);
            }
            
        }
    }
    
    
    //随机布置到每一个位置
    for (int x=0; x<_rows; ++x) {
        for (int y=0; y<_columns; ++y) {
            
            if (x==_rows-1 && y==_columns-1) {
                //最后一块不需要
                _slices[x][y]=nullptr;
                break;
            }
            
            auto length= list.size();
            
            auto value= static_cast<int>(CCRANDOM_0_1()*length);
            
            auto slice=list.at(value);
            list.eraseObject(slice);
            
            _slices[x][y]=slice;
            
            slice->setPosition(y*_sliceWidth,_sliceHeight*_rows-(x+1)*_sliceHeight);
        }
    }
    
}

bool CuttingPhotos::checkIsWin()
{
    bool isWin = true;
    for (int x=0; x<_rows; ++x) {
        for (int y=0; y<_columns; ++y) {
            auto slice =_slices[x][y];
            if(slice){
                auto target = slice->getPosition();
                auto x = _rows - 1 - floorf(target.y/_sliceHeight);
                auto y = floor(target.x/_sliceWidth);
                if(y+_rows*x != slice->getTag()){
                    isWin = false;
                }
            }
        }
    }
    if(isWin) CCLOG("麻痹我无语了。。。。");
    return isWin;
}

void CuttingPhotos::restartGame()
{
//    do{
        restart();
//    }while (checkIsWin());
}